package com.starinside.wp.controller.api;

import com.alibaba.fastjson.JSON;
import com.dotflat.utils.DateUtil;
import com.google.common.collect.ImmutableMap;
import com.starinside.wp.domain.*;
import com.starinside.wp.domain.liveRoom.LiveRoom;
import com.starinside.wp.foundation.DO.LiveRoomDO;
import com.starinside.wp.foundation.dto.AreaSettingDTO;
import com.starinside.wp.foundation.exception.BusinessException;
import com.starinside.wp.foundation.model.ErrorCode;
import com.starinside.wp.foundation.model.StatusResponse;
import com.starinside.wp.foundation.vo.BindedBabyVO;
import com.starinside.wp.foundation.vo.ChildrenVo;
import com.starinside.wp.repository.AppUserRepository;
import com.starinside.wp.repository.ChildrenExtendInfoRepository;
import com.starinside.wp.repository.RelAreaLiveRecordRepository;
import com.starinside.wp.repository.UserChildrenRepository;
import com.starinside.wp.service.BindedBabyService;
import com.starinside.wp.service.LiveRoomService;
import com.starinside.wp.service.SsoCallService;
import com.starinside.wp.utils.RemoteCallUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static com.starinside.wp.foundation.constant.RequestConstant.TICKET;

@RestController
@RequestMapping("/wx/api/liveroom")
@Api(value="/wx/api/liveroom", tags = "摄像头")
@Slf4j
public class APILiveRoomController {

    @Autowired
    private BindedBabyService bindedBabyService;

    @Autowired
    private LiveRoomService liveRoomService;

    @Autowired
    private UserChildrenRepository userChildrenRepository;

    @Autowired
    private ChildrenExtendInfoRepository childrenExtendInfoRepository;

    @Autowired
    private RelAreaLiveRecordRepository relAreaLiveRecordRepository;

    @Value("${sso.server.url}")
    String ssoServerUrl;

    @Value("${teach.server.url}")
    String teachUrl;

    @Autowired
    private SsoCallService ssoCallService;

    private static final String LIVE_ROOM_SWITCH_KEY = "LIVE_ROOM_SWITCH_KEY";
    
    @ApiOperation("有权限的摄像头列表")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public StatusResponse doBindDevice(@RequestHeader(TICKET) String ticket, HttpServletRequest req, HttpServletResponse resp){
        WxUser user = (WxUser) req.getSession().getAttribute("loginUser");

        if (StringUtils.isEmpty(user.getParentId()) || StringUtils.isEmpty(user.getDefaultBabyId()) || StringUtils.isEmpty(user.getParentMobile())) {
            return StatusResponse.error(ErrorCode.CHILDREN_NOT_EXIST, "当前账号下没有宝宝信息");
        }
        List<RelUserChildren> ucs = userChildrenRepository.findByUserIdAndCameraEnabled(user.getParentId(), true);
        if (ucs == null || ucs.size() == 0) {
            return StatusResponse.error(ErrorCode.SIGN_ERROR, "当前账号没有开通摄像头权限，请联系园区负责人。");
        }
        String[] ids = ucs.stream().map(k -> {
            return k.getChildrenId();
        }).toArray(String[]::new);
        //查出有权限可以拥有摄像头宝宝
        List<BindedBabyVO> babies1 = bindedBabyService.getAllBindedBabyEffective(ids);
        if (babies1.size()==0){
            return StatusResponse.error(ErrorCode.SIGN_ERROR, "监控服务已过有效期。");
        }
        //校验有摄像头开关签到的宝宝
        List<BindedBabyVO> babies2 = new ArrayList<>();
        //签到开关集合
        List<AreaSettingDTO> settingDTOList = getListAreaSettingDTO(babies1);
        //宝宝详情集合
        List<String> childrenIdList = babies1.stream().map(k -> k.getId()).collect(Collectors.toList());
        List<ChildrenExtendInfo> childrenExtendInfoList = childrenExtendInfoRepository.findByChildrenIdIn(childrenIdList);
        babies1.stream().filter(o -> o.getStatus() == 1).forEach(o -> {
            AreaSettingDTO relAreaLiveRecord = getAreaSettingDTO(settingDTOList, o.getAreaId());
            boolean b = true;
            //判断是否有开关配置
            if (null != relAreaLiveRecord) {
                //判断签到开关打开
                if (StringUtils.equals(relAreaLiveRecord.getValue(), "1")) {
                    ChildrenExtendInfo extendInfo = getChildrenExtendInfo(childrenExtendInfoList,o.getId());
                    //当天没签到 跳过
                    if (null != extendInfo.getCheckTime()) {
                        String currentDay = DateUtil.millisToDateTime(new Date().getTime(), "yyyy-MM-dd");
                        String cheDate = DateUtil.formatDayToStr(extendInfo.getCheckTime());
                        //签到不是今天，签到状态不为入园 跳过
                        if (!cheDate.equals(currentDay) || extendInfo.getCheckStatus() != 1) {
                            b =false;
                        }
                    }else {
                        b =false;
                    }
                }
            }
            if (b){
                babies2.add(o);
            }
        });
        if (babies2.size() <= 0) {
            return StatusResponse.error(ErrorCode.SIGN_ERROR, "宝宝未签到。");
        }

        List result = liveRoomService.getAllValidLiveRoomDO(babies2);

//        if(result == null || result.size() == 0){
//            result = new ArrayList();
//
//            LiveRoomDO d = new LiveRoomDO();
//            {
//                //active: true
//                //areaId: "2c908059793cd249017a3cb7122001b6"
//                //channelNo: 23
//                //created: 1624672740000
//                //deviceSerial: "F58897010"
//                //exception: 0
//                //hdurl: "rtmp://rtmp01open.ys7.com/openlive/988ffdcab0aa4d708f5b2a58bd8ef223.hd"
//                //hls: "http://hls01open.ys7.com/openlive/988ffdcab0aa4d708f5b2a58bd8ef223.m3u8"
//                //hlsHd: "http://hls01open.ys7.com/openlive/988ffdcab0aa4d708f5b2a58bd8ef223.hd.m3u8"
//                //id: "2c908058793cceed017a3cd090f00eb7"
//                //isPublic: false
//                //liveWay: 2
//                //liveWayVal: "RTMP"
//                //name: null
//                //openTime: "[\"00:00-23:59\"]"
//                //status: 1
//                //statusVal: "直播中"
//                //teachingAreaId: null
//                //thumbUrl: null
//                //type: 1
//                //url: "rtmp://rtmp01open.ys7.com/openlive/988ffdcab0aa4d708f5b2a58bd8ef223"
//                //yingshiId: null
//                d.setAreaId("2c908059793cd249017a3cb7122001b6");
//                d.setChannelNo(23);
//                d.setId("2c908058793cceed017a3cd090f00eb7");
//                d.setDeviceSerial("F58897010");
//                d.setActive(true);
//            }
//
//            result.add(d);
//        }

        return StatusResponse.success(result);
    }
    //签到开关集合
    public List<AreaSettingDTO> getListAreaSettingDTO(List<BindedBabyVO> babies) {
        List<AreaSettingDTO> settingDTOList = new ArrayList<>();
        Map areaIds = new HashMap();
        babies.stream().filter(o -> o.getStatus() == 1).forEach(o -> {
            areaIds.put(o.getAreaId(), o.getAreaId());
        });
        Set set = areaIds.keySet();
        for (Object o : set) {
            AreaSettingDTO relAreaLiveRecord = ssoCallService.getAreaSetting(LIVE_ROOM_SWITCH_KEY, String.valueOf(o));
            if (null != relAreaLiveRecord) {
                settingDTOList.add(relAreaLiveRecord);
            }
        }
        return settingDTOList;
    }
    //查询园区签到开关
    public AreaSettingDTO getAreaSettingDTO(List<AreaSettingDTO> settingDTOList, String areaId) {
        AreaSettingDTO settingDTO = null;
        for (int i = 0; i < settingDTOList.size(); i++) {
            AreaSettingDTO setting = settingDTOList.get(i);
            if (StringUtils.equals(areaId, setting.getAreaId())) {
                settingDTO = settingDTOList.get(i);
                break;
            }
        }
        return settingDTO;
    }
    //查询学生详情
    public ChildrenExtendInfo getChildrenExtendInfo(List<ChildrenExtendInfo> childrenExtendInfoList, String id) {
        ChildrenExtendInfo childrenExtendInfo = null;
        for (int i = 0; i < childrenExtendInfoList.size(); i++) {
            ChildrenExtendInfo childrenExtendInfo1 = childrenExtendInfoList.get(i);
            if (StringUtils.equals(id, childrenExtendInfo1.getChildrenId())) {
                childrenExtendInfo = childrenExtendInfoList.get(i);
                break;
            }
        }
        return childrenExtendInfo;
    }

    @ApiOperation("获取播放器地址")
    @RequestMapping(value = "/playerURL", method = RequestMethod.GET)
    public StatusResponse playerURL( @RequestHeader(TICKET) String ticket,  HttpServletRequest req, String roomId){
        WxUser user = (WxUser) req.getSession().getAttribute("loginUser");

        if(StringUtils.isEmpty(user.getParentId()) || StringUtils.isEmpty(user.getDefaultBabyId()) || StringUtils.isEmpty(user.getParentMobile())){
            return StatusResponse.error(ErrorCode.CHILDREN_NOT_EXIST,"当前账号下没有宝宝信息");
        }

        List<RelUserChildren> ucs = userChildrenRepository.findByUserIdAndCameraEnabled(user.getParentId(), true);

        if(ucs == null || ucs.size() == 0){
            return StatusResponse.error(ErrorCode.SIGN_ERROR,"当前账号没有开通摄像头权限，请联系园区负责人。");
        }

        String[] ids = ucs.stream().map(k -> {
            return k.getChildrenId();
        }).toArray(String[]::new);

        List<LiveRoom> result = liveRoomService.getAllValidLiveRoom(ids);

//        if (roomId.equals("2c908058793cceed017a3cd090f00eb7")){
//            LiveRoom liveRoom = liveRoomService.get("2c908058793cceed017a3cd090f00eb7", "2c908059793cd249017a3cb7122001b6");
//            String url = liveRoomService.getLiveRoomHLSAddress(liveRoom);
//            return StatusResponse.success(url);
//        }

        for (LiveRoom liveRoom : result){
            if (liveRoom.getId().equals(roomId)){
                String url = liveRoomService.getLiveRoomHLSAddress(liveRoom);
                return StatusResponse.success(url);
            }
        }

        throw new BusinessException(ErrorCode.AREA_LIVE_ROOM_DUPLICATE, "获取播放地址失败");
    }

    @ApiOperation(value = "更新 - 使用时间",httpMethod = "POST")
    @RequestMapping("/update_date")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "liveRoomId", value = "摄像头ID", required = true, dataType = "string"),
    })
    public StatusResponse updateDate(@RequestHeader(TICKET) String ticket, String liveRoomId) {
        liveRoomService.updateDate(liveRoomId);
        return StatusResponse.success();
    }

    @ApiOperation(value = "打开 - 摄像头",httpMethod = "POST")
    @RequestMapping("/open_live")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "liveRoomId", value = "摄像头ID", required = true, dataType = "string"),
    })
    public StatusResponse open_live(@RequestHeader(TICKET) String ticket, HttpServletRequest req, String liveRoomId)  {
        WxUser user = (WxUser) req.getSession().getAttribute("loginUser");

        LiveRoom lr = liveRoomService.get(liveRoomId);

        if (lr == null){
            return StatusResponse.error(ErrorCode.AREA_LIVE_ROOM_DUPLICATE, "摄像头不存在!");
        }
        if (lr.getIpOnline()){
            return StatusResponse.success(1);
        }

        List<BindedBabyVO> babies = bindedBabyService.getAllBindedBabyByParent(user.getParentId());

        boolean founded = false;
        for ( BindedBabyVO vo : babies){
            if (vo.getAreaId().equals(lr.getAreaId())){
                founded = true;
            }
        }

        if (!founded){
            return StatusResponse.error(ErrorCode.AREA_LIVE_ROOM_DUPLICATE, "摄像头不存在!!");
        }

        return StatusResponse.success(liveRoomService.openLive(lr));

//        return StatusResponse.success(1);
    }

    @ApiOperation(value = "关闭 - 摄像头", httpMethod = "POST")
    @RequestMapping("/close_live")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "liveRoomId", value = "摄像头ID", required = true, dataType = "string"),
    })
    public StatusResponse close_live(@RequestHeader(TICKET) String ticket, String liveRoomId) {
//        liveRoomService.closeLive(liveRoomId);
        return StatusResponse.success();
    }

}
